package com.jdkreader.concurrency.concurrent.simulation;


import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 经理，负责管理和调配服务员
 */
public class TellerManager implements Runnable{

    //private static Random random=new Random(47);

    private ExecutorService exec;

    private CustomerLine customers;
    //调度时间
    private int adjustmentPeriod;

    private PriorityQueue<Teller> workingTellers=new PriorityQueue<>();

    private Queue<Teller> tellersDoingOtherThings=new LinkedList<>();

    public TellerManager(ExecutorService exec,CustomerLine customers,int adjustmentPeriod){
        this.exec=exec;
        this.customers=customers;
        this.adjustmentPeriod=adjustmentPeriod;

        //初始化一个服务员
        Teller teller=new Teller(customers);
        exec.execute(teller);
        workingTellers.add(teller);

    }

    /**
     * 当顾客过多时调整服务员数量
     */
    public void adjustTellerNum(){

        if(customers.size() / workingTellers.size() >2){
            if(tellersDoingOtherThings.size() >0){
                Teller teller=tellersDoingOtherThings.remove();
                teller.serverCustomerLine();
                workingTellers.offer(teller);
                return;
            }
        }
        //可用服务员数量不够，创建（雇佣）服务员
        Teller teller=new Teller(customers);
        exec.execute(teller);
        workingTellers.add(teller);

        if(customers.size() > 1 &&
            customers.size() / workingTellers.size() < 2){
            releasingOneTeller();
            if(customers.size() == 0){
                while(workingTellers.size() > 1){
                    releasingOneTeller();
                }
            }
        }
    }

    private void releasingOneTeller(){
        Teller teller=workingTellers.remove();
        teller.doSomeThingElse();
        tellersDoingOtherThings.offer(teller);
    }

    public void run(){

        try{
            while(!Thread.interrupted()){
                TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
                adjustTellerNum();
                System.out.println("Customers{");
                for(Teller teller:workingTellers){
                    System.out.println(teller.shortString());
                }
                System.out.println("}");
            }
        }catch(InterruptedException e){
            System.out.println(this+" interrupted");
            e.printStackTrace();
        }

        System.out.println(this+" terminating ");
    }



}
